<template>
  <el-container>
    <el-aside width="790px">
      <el-image fit="contain" :src="loginLeftImg"></el-image>
    </el-aside>
    <el-main>
      <el-card class="box-card login-card">
        <span class="login-title">元动力后台管理系统</span>
        <span class="login-tip">welcome 欢迎登陆</span>
        <el-form ref="formRef" :model="user" label-width="80px" :rules="loginRules">
          <el-form-item label="用户名" prop="userName">
            <el-input v-model="user.userName" placeholder="请输入用户"></el-input>
          </el-form-item>
          <el-form-item label="密码" prop="password">
            <el-input v-model="user.password" type="password" placeholder="请输入密码" show-password></el-input>
          </el-form-item>
          <el-form-item>
            <el-button class="login-button" type="primary" @click="doLogin" :loading="isLoggingIn"><template #loading>
                <div class="custom-loading">
                  <svg class="circular" viewBox="-10, -10, 50, 50">
                    <path class="path"
                      d="M 30 15 L 28 17 M 25.61 25.61 A 15 15, 0, 0, 1, 15 30 A 15 15, 0, 1, 1, 27.99 7.5 L 15 15"
                      style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)" />
                  </svg>
                </div>
              </template>登陆</el-button>
          </el-form-item>
        </el-form>
      </el-card>
    </el-main>
  </el-container>
</template>

<script setup>
import { reactive, ref } from "vue";
import loginLeftImg from "@/assets/images/login_left.png";
import store from "@/store";
import router from "@/router";
import { ElMessage } from "element-plus";

const user = ref({
  userName: "admin",
  password: "111111111",
});

const loginRules = reactive({
  userName: [
    { required: true, trigger: "blur", message: "用户名不能为空" },
    { min: 5, max: 16, trigger: "blur", message: "用户名长度必须在5到16个字符之间" },
  ],
  password: [
    { required: true, trigger: "blur", message: "密码不能为空" },
    { min: 9, max: 20, trigger: "blur", message: "密码长度必须在9到20个字符之间" },
  ],
  code: [{ required: true, trigger: "change", message: "验证码不能为空" }],
});

const formRef = ref();
const isLoggingIn = ref(false);

const doLogin = async () => {
  if (isLoggingIn.value) return;
  isLoggingIn.value = true;
  ElMessage.closeAll();
  try {
    await formRef.value?.validate();
    await store.dispatch("LOGIN", user.value);
    await store.dispatch("GET_INFO");
    router.push("/");
    ElMessage.success({
      message: "登录成功",
      duration: 1000,
    });
  } catch (error) {
    let errorMsg = "登录失败";
    if (error?.userName || error?.password) {
      // 表单验证错误
      const firstError = Object.values(error).flat().shift();
      errorMsg = firstError?.message || "表单验证失败";
    } else if (error?.response) {
      // HTTP 错误
      errorMsg = error.response.data?.message || "用户名或密码错误";
    } else {
      errorMsg = error.message || "未知错误";
    }
    ElMessage.error({ message: errorMsg, showClose: true, duration: 3000 });
  } finally {
    isLoggingIn.value = false;
  }
};
</script>

<style scoped>
.login-button {
  width: 80px;
}

.el-button .custom-loading .circular {
  margin-right: 6px;
  width: 18px;
  height: 18px;
  animation: loading-rotate 2s linear infinite;
}

.el-button .custom-loading .circular .path {
  animation: loading-dash 1.5s ease-in-out infinite;
  stroke-dasharray: 90, 150;
  stroke-dashoffset: 0;
  stroke-width: 2;
  stroke: var(--el-button-text-color);
  stroke-linecap: round;
}

.el-image {
  width: auto;
}

.el-main {
  position: relative;
}

.login-card {
  position: absolute;
  top: 0;
  left: -50px;
  bottom: 0;
  right: 0;
  margin: auto;
  width: 75%;
  height: 55%;
  padding: 50px;
}

.login-title {
  width: 459px;
  height: 70px;
  font-size: 40px;
  font-family: AlibabaPuHuiTiB;
  color: #333333;
  line-height: 90px;
  letter-spacing: 1px;
  font-weight: 800;
  display: block;
  text-align: left;
}

.login-tip {
  width: 319px;
  height: 70px;
  font-size: 30px;
  font-family: PingFangSC-Regular, PingFang SC;
  font-weight: 400;
  color: #999999;
  line-height: 90px;
  letter-spacing: 1px;
  display: block;
  text-align: left;
  margin-bottom: 30px;
}
</style>
